# -*- coding: utf-8 -*-
# © 2018 QYT Technology
import time
# import pickle
import os, re
from collections import OrderedDict
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from retrying import retry
import datetime
import configparser


class historySpider():
    origin_rule_list = []
    rule_list = []
    double_rule_list = []
    double_rule_value = []
    record = {}  # 用来计算中奖
    biggest = 0 # 最大投注次数
    all_biggest = 0
    rule_file = os.path.join(os.path.curdir, 'rule.txt')
    double_rule_file = os.path.join(os.path.curdir, 'double_rule.txt')
    def get_server(self):
        path = os.path.join(os.path.curdir, 'chromedriver')
        browser = webdriver.Chrome(path)
        browser.get('http://www.h5h.net/bjpk10/')
        time.sleep(2)
        self.browser = browser
        return self.browser

    def __init__(self):
        ######直接初始化到赛车页面
        # self.read_record()  # 可以单独调用
        # self.browser = self.get_server()
        pass

    def add_history(self, data, date_time):
        """
        add_record("dd, sada,1 ,1312")
        """
        history_file = os.path.join(os.path.curdir, '%shistory.txt'%date_time)
        data = str(data) + '\r\n'
        with open(history_file, 'a') as f:
            f.writelines(data)

    def read_history(self, date_time):
        try:
            history_file = os.path.join(os.path.curdir, 'data', '%shistory.txt'%date_time)
            with open(history_file, 'r') as f:
                return f.readlines()
        except:
            return []

    def add_record(self, data, date_time):
        """
        add_record("dd, sada,1 ,1312")
        """
        data = str(data) + '\r\n'
        record_file = os.path.join(os.path.curdir, '%srecord.txt'%date_time)

        with open(record_file, 'a', encoding='utf8') as f:
            f.writelines(data)

    def add_rule_record(self, data, date_time):
        """
        add_record("dd, sada,1 ,1312")
        """
        data = str(data) + '\r\n'
        record_file = os.path.join(os.path.curdir, '%s_%s_%s_%s_rule_record.txt'%(date_time, line, peilv, self.value_count))

        with open(record_file, 'w', encoding='utf8') as f:
            f.writelines(data)

    def loop(self, start_t, end_t):
        """
        拉数据
        :param start_t:
        :param end_t:
        :return:
        """
        start = datetime.datetime.strptime(start_t, '%Y-%m-%d')
        end = datetime.datetime.strptime(end_t, '%Y-%m-%d')
        delta = datetime.timedelta(days=1)

        count = abs(end - start)
        for _ in range(count.days+1):
            self.get_history(start.strftime('%Y-%m-%d'))
            self.get_data()
            start += delta

    def test_loop(self, start_t, end_t):
        start = datetime.datetime.strptime(start_t, '%Y-%m-%d')
        end = datetime.datetime.strptime(end_t, '%Y-%m-%d')
        delta = datetime.timedelta(days=1)

        count = abs(end - start)
        self.read_rule()
        self.all_count = 0  # 单日
        for _ in range(count.days+1):
            self.test_follow_rules(start.strftime('%Y-%m-%d'))
            start += delta

    def test_double_loop(self, start_t, end_t, mode):
        start = datetime.datetime.strptime(start_t, '%Y-%m-%d')
        end = datetime.datetime.strptime(end_t, '%Y-%m-%d')
        delta = datetime.timedelta(days=1)

        count = abs(end - start)
        self.read_double_rule()
        self.all_count = 0
        for _ in range(count.days+1):
            self.test_double_rules(start.strftime('%Y-%m-%d'), mode)
            start += delta
        print('all bbbb%s'%self.all_biggest)

    def get_history(self, data):
        js = "document.getElementById('calendar').removeAttribute('readonly')"
        self.browser.execute_script(js)

        date_pick = self.browser.find_element_by_id('calendar')
        date_pick.clear()
        date_pick.send_keys(data)
        tmp = self.browser.find_element_by_xpath('//*[@id="dateframe"]/div[1]')
        tmp.click()
        date_pick.click()
        submit = self.browser.find_element_by_id('laydate_ok')
        submit.click()

    def get_data(self):
        nice_list = []
        last_date_time = '-------'
        time.sleep(5)
        for i in range(1,179):
            try:
                date_time = self.browser.find_element_by_xpath('//*[@id="dataList"]/table/tbody/tr[%d]/td[1]' % i).text
                last_date_time = date_time
                serial = self.browser.find_element_by_xpath('//*[@id="dataList"]/table/tbody/tr[%d]/td[2]' % i).text
            except:
                date_time = last_date_time
                serial = '-------'
            datas = ''
            for n in range(1,11):
                try:
                    data = self.browser.find_element_by_xpath(
                        '//*[@id="dataList"]/table/tbody/tr[%d]/td[3]/div[%d]'%(i, n)).get_attribute('data-num')
                    if int(data) == 10:
                        data = 0
                except:
                    data = ' '
                datas += str(data)
            print(date_time, serial, datas)
            self.add_history('%s,%s,%s'%(date_time, serial, datas), date_time.split(' ')[0])
            nice_list.append((date_time, serial, datas))
        return nice_list

    def read_rule(self):
        """
        初始化跟投规则
        """
        try:
            with open(self.rule_file, 'r') as f:
                rule_list = f.readlines()
                for rule in rule_list:
                    rule = rule.split('\n')[0]
                    if rule:
                        rule = rule.split('|')
                        # print(rule)
                        self.origin_rule_list.append([rule[0], rule[1], rule[2]])
                        self.value_count = len(rule[2].split('-'))  # 允许失败次数
                        self.rule_list.append([int(rule[0]), [int(i) for i in rule[1]], rule[2].split('-'), 0, 0])
            return self.rule_list
        except IOError:
            pass

    def read_double_rule(self):
        """
        初始化跟投规则 跟上一期的 所以只有金额
        |1-1-3-7-15-32-67-138-280-565|
        """
        try:
            with open(self.double_rule_file, 'r') as f:
                rule_list = f.readlines()
                for rule in rule_list:
                    rule = rule.split('\n')[0]
                    if rule:
                        rule = rule.split('|')
                        # print(rule)
                        self.origin_rule_list.append([rule[0]])
                        self.value_count = len(rule[0].split('-'))  # 允许失败次数
                        self.double_rule_value.append(rule[0].split('-'))
            return self.double_rule_value
        except IOError:
            pass

    def get_lottery_res(self, date_time):
        history_list = self.read_history(date_time)
        history_list.reverse()
        return history_list

    # def single_or_double(self, date_time):
    #     """
    #     转换成单双
    #     :param date_time:
    #     :return:
    #     """
    #     number_list = []
    #     history_list = self.read_history(date_time)
    #     history_list.reverse()
    #     history_list = [history.split(',') for history in history_list]
    #     for history in history_list:
    #         number = ['单' if int(i)%2 else '双' for i in history[2].strip('\n')]
    #         number_list.append(number)
    #     return number_list
    #
    # def big_or_small(self, date_time):
    #     """
    #     转换成大小
    #     :param date_time:
    #     :return:
    #     """
    #     number_list = []
    #     history_list = self.read_history(date_time)
    #     history_list.reverse()
    #     history_list = [history.split(',') for history in history_list]
    #     for history in history_list:
    #         number = ['大' if int(i)>5 or int(i) == 0 else '小' for i in history[2].strip('\n')]
    #         number_list.append(number)
    #     return number_list

    def test_double_rules(self, date_time, mode):
        """
        单双大小等
        :param date_time:
        mode: single or big
        :return:
        """
        history_list = self.get_lottery_res(date_time)  # 期数，开奖号码
        if not history_list:
            return
        self.record = {}
        self.double_rule_list = []
        self.biggest = 0
        # 根据第一期生成规则
        base_rule = history_list[0]  # 第一期参考
        base_rule = base_rule.split(',')
        if '-------' not in base_rule[1]:
            number = int(base_rule[1])
            base_rule = [int(i) for i in base_rule[2].strip('\n')]

        for index, win_number in enumerate(base_rule):  # 转化序列
            if mode == 'single':
                win_number = '单' if int(win_number) % 2 else '双'
            elif mode == 'big':
                win_number = '大' if int(win_number) > 5 or int(win_number) == 0 else '小'

            for rule in self.double_rule_value:
                self.double_rule_list.append([index, win_number, rule, 0, 0, 1])  # 名次, 结果, [], 次数，盈利，是否能投注 默认可以

        print(self.double_rule_list)
        #
        # for rule in self.double_rule_list:  # 统计清0
        #     rule[3] = 0  # 次数
        #     rule[4] = 0  # 盈利
        #     rule[5] = 1  # 是否能投注
        line1 = int(line)
        if line1 >= len(history_list):
            line1 = len(history_list) - 1  # 留最后一次判断
        data = ''
        count = 0
        err = False
        for history in history_list[1:line1]:
            history = history.split(',')
            if '-------' not in history[1]:
                number = int(history[1])
                self.number_list = [int(i) for i in history[2].strip('\n')]

                # self.add_record_list = []
                for rule_serial, rule in enumerate(self.double_rule_list):
                    self._adjust_double_winning(rule_serial, rule, mode)
                try:
                    # self.adjust_times()
                    # 返回流水
                    for rule_serial, rule in enumerate(self.double_rule_list):
                        if rule[5]:  # 是否能投注
                            self.sub_double_value(rule)
                            rank = rule[0] # 投注位置
                            # value = int(rule[2][rule[3]-1])
                            # self.add_record(
                            #     "%s,%s,%s,%s,%s,%s" % (int(number) + 1, rule_serial, rank + 1, rule[1],
                            #                            value, rule[3]), date_time)  # 期号，规则序号(是否加1), 位置, 投注球, 金额, 手数
                            self.record[rule_serial] = [rank, rule[3]]
                except Exception as e:
                    print(e)
                    err = True
                    data = '>>>>>>>>>>>>%s>>>>>>>>>>>>>\r\n' % self.value_count
                    break

        if not err:  # 没有错误的话 最后一次判断结果
            history = history_list[line1].split(',')
            if '-------' not in history[1]:
                self.number_list = [int(i) for i in history[2].strip('\n')]
            for rule_serial, rule in enumerate(self.double_rule_list):
                self._adjust_double_winning(rule_serial, rule, mode)

            # [3, [1, 7, 8, 9, 0], ['1', '1', '3', '7', '15', '32', '67', '138', '280', '565', '1140'], 6, 135.09599999999995]
        for t in self.double_rule_list:
            count = round(count + t[4], 2)
            tmp1 = ''
            # print(self.value_count)
            for i in range(self.value_count):
                tmp1 = tmp1 + str(t[2][i]) + '-'
            data = data + '%s|%s|%s|%s' % (t[0], t[1], tmp1, round(t[4], 2)) + '\r\n'
        data = data + str(count)
        print(data)
        self.all_count = round(self.all_count + count, 2)
        print(self.all_count)
        print('>>>>>>>>>>biggest%s'%self.biggest)
        # data_count = '%s ,%s, %s' % (date_time, count, self.biggest)
        data_count = '%s , %s' % (date_time, self.biggest)

        self.all_biggest = self.biggest if self.all_biggest < self.biggest else self.all_biggest
        # self.add_rule_record(data, date_time)
        self.add_count(data_count)

    def test_follow_rules(self, date_time):
        """
        位置跟投
        :param target_rule_list: 需要执行的规则序列号 这里的编号从0开始
        :return:
        """
        history_list = self.get_lottery_res(date_time)  # 期数，开奖号码
        if not history_list:
            return
        self.record = {}
        for rule in self.rule_list:  # 统计清0
            rule[3] = 0
            rule[4] = 0
        line1 = int(line)
        if line1 >= len(history_list):
            line1 = len(history_list) -1  # 留最后一次判断
        data = ''
        count = 0
        err = False
        for history in history_list[:line1]:
            history = history.split(',')
            if '-------' not in history[1]:
                number = int(history[1])
                self.number_list = [int(i) for i in history[2].strip('\n')]

                # self.add_record_list = []
                for rule_serial, rule in enumerate(self.rule_list):
                    self._adjust_winning(rule_serial, rule)
                try:
                    self.adjust_times()

                    # 返回流水
                    for rule_serial, rule in enumerate(self.rule_list):
                        self.sub_value(rule)
                        rank = self.number_list.index(rule[0])  # 名次x坐标
                        # value = int(rule[2][rule[3]-1])
                        # self.add_record(
                        #     "%s,%s,%s,%s,%s,%s" % (int(number) + 1, rule_serial, rank + 1, self.list_to_str(rule[1]),
                        #                            value, rule[3]), date_time)  # 期号，规则序号(是否加1), 位置, 投注球, 金额, 手数
                        self.record[rule_serial] = [rank, rule[3]]
                except Exception as e:
                    print(e)
                    err = True
                    data = '>>>>>>>>>>>>%s>>>>>>>>>>>>>\r\n'%self.value_count
                    break

        if not err:  # 没有错误的话 最后一次判断结果
            history = history_list[line1].split(',')
            if '-------' not in history[1]:
                self.number_list = [int(i) for i in history[2].strip('\n')]
            for rule_serial, rule in enumerate(self.rule_list):
                self._adjust_winning(rule_serial, rule)

        # [3, [1, 7, 8, 9, 0], ['1', '1', '3', '7', '15', '32', '67', '138', '280', '565', '1140'], 6, 135.09599999999995]
        for t in self.rule_list:
            count = round(count + t[4], 2)
            tmp = ''
            tmp1 = ''
            for i in range(5):
                tmp += str(t[1][i])
            # print(self.value_count)
            for i in range(self.value_count):
                tmp1 = tmp1 + str(t[2][i]) + '-'
            data = data + '%s|%s|%s|%s'%(t[0],tmp,tmp1,round(t[4],2)) + '\r\n'
        data = data + str(count)
        print(data)
        self.all_count = round(self.all_count + count, 2)
        print(self.all_count)
        data_count = '%s ,%s'%(date_time, count)
        self.add_rule_record(data, date_time)
        self.add_count(data_count)

    def list_to_str(self, enter_list):
        target_str = ''
        for i in enter_list:
            target_str += str(i)
        return target_str

    def add_count(self, data):
        data = str(data) + '\r\n'
        record_file = os.path.join(os.path.curdir, 'rule_count_%s.txt'%peilv)

        with open(record_file, 'a') as f:
            f.writelines(data)

    #
    # def follow_rule(self, rule_serial, number):
    #     print('开始投注')
    #     # self._adjust_winning(rule_serial, self.rule_list[rule_serial])
    #     return self._follow_rule(rule_serial, self.rule_list[rule_serial], number)

    # def _follow_rule(self, serial, rule, number, date_time):
    #     """
    #     跟投规则
    #     编号、规则、期数
    #     :param follow_list: []
    #     :return 703697,2,10,[3, 7, 8, 9, 0],3,1
    #     """
    #
    #     rank = self.number_list.index(rule[0])  # 名次x坐标
    #
    #     self.sub_value(serial, rule)
    #     self.add_record("%s,%s,%s,%s,%s,%s"%(int(number)+1, serial, rank+1, rule[1], rule[3], value), date_time)
    #     # self.add_record_list.append("%s,%s,%s,%s,%s,%s"%(int(number)+1, serial+1, rank+1, rule[1], value, rule[3]))
    #     self.record[serial] = [rank, rule[3]]
    #     enter_number = ''
    #     for i in rule[1]:
    #         enter_number += str(i)
    #     return "%s,%s,%s,%s,%s,%s"%(int(number)+1, serial, rank+1, enter_number, value, rule[3])

    # def adjust_winning(self, target_rule_list):
    #     """
    #     刷规则盈利
    #     """
    #     print('刷规则盈利')
    #     self._get_lottery_res()  # 期数，开奖号码
    #     res = False
    #     for rule_serial in target_rule_list:
    #         if self._adjust_winning(rule_serial, self.rule_list[rule_serial]):
    #             res = True  # 停止所有投注
    #     return res, self.rule_list

    def adjust_times(self):
        for index, rule in enumerate(self.rule_list):
            if rule[3] > self.value_count - 1:# 任意一条规则 12次表示认输 一切停止
                print("%s超过%s次"%(index, self.value_count))
                raise Exception

    def sub_value(self, rule):
        """
        投注后减去本次成本
        """
        value = rule[2][rule[3]]  # 本次投注金额
        rule[4] = round(rule[4] - int(value) * 5, 2)  # 先扣掉投注的资金
        # print('ddddddd'+str(rule[4]))
        rule[3] += 1  # 次数+1

    def sub_double_value(self, rule):
        """
        投注后减去本次成本
        """
        # value = rule[2][rule[3]]  # 本次投注金额
        # rule[4] = round(rule[4] - int(value), 2)  # 先扣掉投注的资金
        # print('ddddddd'+str(rule[4]))
        rule[3] += 1  # 次数+1

    def _adjust_winning(self, serial, rule):  # TODO: 加入期号判断
        """
        是否中奖
        ['ball', ['follow_list'], ['value_list'], 'times', 'left']
        :return:
        """
        if serial in self.record:  # 第一次是空的
            rank = self.record[serial][0]
            win_number = self.number_list[rank]
            value = rule[2][rule[3]-1]  # 上次投注金额 已经被+1
            if win_number in rule[1]:
                self.record[serial][1] = 0  # 重置次数
                rule[3] = 0
                rule[4] = round(rule[4] + int(value) * peilv, 2)

    def _adjust_double_winning(self, serial, rule, mode):  # TODO: 加入期号判断
        """
        单双是否中奖
        [0, 单, ['value_list'], 'times', 'left']
        mode: single / big
        :return:
        """
        if serial in self.record:  # 第一次是空的
            rank = self.record[serial][0]
            win_number = self.number_list[rank]
            if mode == 'single':
                win_number = '单' if int(win_number) % 2 else '双'
            elif mode == 'big':
                win_number = '大' if int(win_number)>5 or int(win_number) == 0 else '小'
            # value = rule[2][rule[3]-1]  # 上次投注金额 已经被+1
            self.biggest = rule[3] if self.biggest < rule[3] else self.biggest
            if win_number == rule[1]:
                if rule[5]:
                    self.record[serial][1] = 0  # 重置次数
                    rule[3] = 0
                    # rule[4] = round(rule[4] + int(value) * peilv, 2)
                    rule[5] = 1
                else:  # 表示上一把是休息，下一把开始投
                    rule[5] = 1
            else:
                # 如果没中, 先休息，直到下次出现再投注
                rule[5] = 0

    def sum_rule(self):
        self.read_rule()
        rule_dict = {}
        for rule in self.rule_list:
            """
            7|13456|1-1-3-7-15-32-67-138-280-565-1140|
            7|13458|1-1-3-7-15-32-67-138-280-565-1140|
            7 1:15 3:15 4:15
            7 1:32 3:32 8:32

            7 1:46 3:47 4:15 8:32
            """
            target_number = rule[0]
            target_rule = rule[1]
            value = int(rule[2][rule[3]])
            number_value_dict = {}

            exist_number_value_dict = rule_dict.get(target_number)
            if exist_number_value_dict:
                for index in target_rule:
                    count_value = exist_number_value_dict.get(index)
                    if count_value:
                        exist_number_value_dict[index] += value
                    else:
                        exist_number_value_dict[index] = value
            else:
                for index in target_rule:
                    number_value_dict[index] = value
                rule_dict[rule[0]] = number_value_dict
        return rule_dict


if __name__ == "__main__":

    config = configparser.ConfigParser()
    config_ini = os.path.join(os.path.curdir, 'config.ini')

    config.read(config_ini)
    config.items('DEFAULT')
    enable_date = config['DEFAULT']['enable_date']
    start_date = config['DEFAULT']['start_date']
    end_date = config['DEFAULT']['end_date']

    enable_test = config['DEFAULT']['enable_test']
    test_start_date = config['DEFAULT']['test_start_date']
    test_end_date = config['DEFAULT']['test_end_date']
    line = int(config['DEFAULT']['line'])
    peilv = float(config['DEFAULT']['peilv'])
    #
    history = historySpider()
    # if enable_date == 'yes':
    #     history.get_server()
    #     history.loop(start_date, end_date)
    # if enable_test == 'yes':
    #     history.test_loop('2018-01-01', '2018-01-01')

    # history = historySpider()
    history.test_double_loop('2018-06-01', '2018-08-31', 'big')

    # print(history.sum_rule())
    # history.loop('2018-8-8', '2018-9-8')
    # print(history.get_data())
    # # 初始化
    # car = carSpider()
    #
    # # 定时器 re_time
    # # 刷左下角
    # history_number_list = car.set_history_data()
    # # 更新左下数据 history_number_list
    # # 刷盈利
    # res, rule_list = car.adjust_winning([])
    # # rule_list 更新右上规则
    # if res:
    #     pass # 停止所有行为 输惨了
    # # 循环投注
    # for i in []:
    #     record = car.follow_rule(1,1)
    #     # 更新右下数据
    #     res, left_time = car.get_left_time()
    #     if res:
    #         if left_time < 10:
    #             #剩下10s 就不投了
    #             re_time = left_time +30
    #             break
    #     else:
    #         re_time = left_time


    # car.get_lottery_res()
    # print(car.number, car.number_list)
    # car.follow_rules()
    # print(car.add_record_list)
    # 顺序